home *** CD-ROM | disk | FTP | other *** search
-
- package sub_arctic.output;
-
- import java.io.DataInputStream;
- import java.io.IOException;
- import java.io.EOFException;
- import java.util.StringTokenizer;
-
- /**
- * A small stand-alone program to do a translation from PPM format image
- * files to code for statically initializing an in memory loaded_image object.
- * The result of this program is code for five static declarations -- an
- * integer for the width of the image, an integer for the height, array of
- * integers for the RGB values, a static loaded_image, and an accessor
- * function for the image. These entities are declared as <name>_width,
- * <name>_height, <name>_data, _<name> and <name>(), where <name> is the
- * string supplied by the -name command line argument (or the default of
- * "image"). <p>
- *
- * Each element of the static array encodes the value for one
- * pixel in the form 0xaarrggbb, where aa is the hex value for alpha
- * (transparency) rr for red, etc. Currently all alpha values are set to
- * ff (fully opaque). <p>
- *
- * The program can be invoked from the command line using the -name argument
- * to control the declared names. Reads a PPM file from standard input,
- * and produces the resulting declarations on standard output.<p>
- *
- * This program now handles both ASCII and Binary encoded PPM files.
- *
- * @author Scott Hudson
- */
- public class ppm_to_code {
-
- /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
-
- /** No instances of this class */
- private ppm_to_code() {}
-
- /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
-
- /** The input stream we are reading from (this will get wrapped around
- * System.in).
- */
- protected static DataInputStream input_file = null;
-
- /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
-
- /** A tokenizer attached to the string for the current line */
- protected static StringTokenizer current_line = null;
-
- /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
-
- /** Get the next white-space delimited token from the input file */
- protected static String next_token()
- {
- String line, tkn;
-
- /* loop to repeat when we get blank and comment lines */
- for (;;)
- {
- /* init the input stream to standard input if we haven't done that */
- if (input_file == null)
- input_file = new DataInputStream(System.in);
-
- /* if there is no current line, or its exhausted get a new one */
- if (current_line == null || !current_line.hasMoreTokens())
- {
- /* read another line */
- try {
- line = input_file.readLine();
- } catch (IOException ex) {
- /* for now treat error as EOF */
- line = null;
- }
-
- /* build a tokenizer around it */
- if (line != null)
- current_line = new StringTokenizer(line);
-
- /* if there are no tokens in the line, skip it */
- if (current_line.countTokens() == 0)
- {
- current_line = null;
- continue;
- }
- }
-
- /* if we have failed to construct a current line we are at the end */
- if (current_line == null) return null;
-
- /* pull out the next token */
- tkn = current_line.nextToken();
-
- /* if it starts with #, skip the rest of the line and go to next */
- if (tkn.startsWith("#"))
- {
- current_line = null;
- continue;
- }
-
- /* otherwise we return the token */
- return tkn;
- }
- }
-
- /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
-
- /** Get the next token from standard input and try to interpret it as a
- * decimal integer. If this fails we print the given message on System.err
- * and exit.
- *
- * @param String message error message to print on System.err if we fail.
- * @return int integer value of next token treated as a decimal integer.
- */
- protected static int next_int(String message)
- {
- String tkn;
-
- /* get the next token and try to make an integer value out of it */
- tkn = next_token();
- try {
- return (new Integer(tkn)).intValue();
- } catch (NumberFormatException ex) {
- System.err.println(message + " -- giving up.");
- System.exit(2);
- return 0;
- }
- }
-
- /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
-
- /**
- * Write a color out to standard input encoded in a 32 bit hex constant (we
- * use longs here so everything will be unsigned. The result will be in the
- * form "0xaarrggbb".
- *
- * @param long alpha transparency value.
- * @param long r red value.
- * @param long g green value.
- * @param long b blue value.
- */
- protected static void write_hex_color(long alpha, long r, long g, long b)
- {
- long encoding = ((alpha&0xff) << 24) | ((r&0xff) << 16) |
- ((g&0xff) << 8) | (b&0xff);
- System.out.print("0x" + Long.toString(encoding,16));
- }
-
- /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
-
- /** Print a "usage" message and exit */
- protected static void usage()
- {
- System.out.println("Usage: java sub_arctic.output.ppm_to_code " +
- "[-name varname] < input.ppm > output");
- System.exit(3);
- }
-
- /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
-
- /**
- * Main program so we can be invoked from the command line.
- * @param String argv[] arguments passed from the command line.
- */
- public static void main(String argv[])
- {
- String tkn;
- int i,w,h,max_color,r,g,b,len;
- int alpha = 0xff;
- int cnt = 0;
- String name = "image";
- boolean is_binary = false;
-
- /* parse argument(s) */
- len = argv.length;
- for (i=0; i<len; i++)
- {
- if (argv[i].equalsIgnoreCase("-name"))
- {
- if (++i>=len || argv[i].startsWith("-"))
- usage();
- else
- name = argv[i];
- }
- else
- usage();
- }
-
- /* we expect a "P3" first */
- tkn = next_token();
- if (!tkn.equalsIgnoreCase("p3"))
- {
- if (tkn.equalsIgnoreCase("p6"))
- {
- is_binary = true;
- }
- else
- {
- System.err.println(
- "Didn't find PPM magic number (\"P3\" or \"P6\") at head " +
- "of file -- giving up");
- System.exit(1);
- }
- }
-
- /* then width, height, and max_color and decimal constants */
- w = next_int("Didn't find width");
- h = next_int("Didn't find height");
- max_color = next_int("Didn't find max_color");
-
- /* put out start of output */
- System.out.println(" // (generated from ppm file)");
- System.out.println(" protected static int "+name+"_width = " + w + ";");
- System.out.println(" protected static int "+name+"_height = " + h + ";");
- System.out.println(" protected static int[] "+ name+"_data = {");
-
- /* start indented line */
- System.out.print(" ");
-
- /* if we have binary data, do that separately */
- if (is_binary)
- {
- do_binary_data(w,h);
- }
- else
- {
- /* read the body of the data in ASCII */
- for (i=0; i<w*h; i++)
- {
- /* get the RGB components */
- r = next_int("Incomplete color code or short file");
- g = next_int("Incomplete color code or short file");
- b = next_int("Incomplete color code or short file");
-
- /* write out the color */
- write_hex_color(alpha,r,g,b);
- System.out.print(",");
- cnt++;
-
- /* end the line and start another if we are getting too long */
- if (cnt == 6)
- {
- System.out.println();
- System.out.print(" ");
- cnt = 0;
- }
- }
- }
-
- /* close out the initializer */
- System.out.println("};");
-
- /* do the rest of the code */
- System.out.println(" protected static sub_arctic.output.loaded_image _" +
- name + " = null;");
- System.out.println();
- System.out.println(" public static sub_arctic.output.loaded_image " +
- name + "() {");
- System.out.println(" if (_" + name + " == null)");
- System.out.println(" _"+name+" = new sub_arctic.output.loaded_image("
- +name+"_data,");
- System.out.println(" "+name+"_width,"+name+"_height);");
- System.out.println(" return _"+name+";");
- System.out.println(" }");
- }
-
- /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
-
- /**
- * Process binary coded data body. We expect to see 3*w*h bytes of data
- * each representing a color value. We write out initialization code based
- * on this data.
- * @param int w width of image.
- * @param int h height of image.
- */
- protected static void do_binary_data(int w, int h)
- {
- byte data[] = new byte[w*h*3];
- int i,r,g,b;
- int cnt = 0;
-
- /* read the whole thing */
- try {
- input_file.readFully(data);
- } catch (EOFException eof) {
- System.err.println("WARNING: Premature EOF while reading binary data" + " -- writing truncated image");
- } catch (IOException ex) {
- System.err.println("An IO error has occured while reading " +
- "binary data -- giving up");
- System.exit(2);
- }
-
- /* write the init code */
- for (i = 0; i < w*h*3;)
- {
- /* write one pixel */
- r = data[i++]; g = data[i++]; b = data[i++];
- write_hex_color(0xff, r,g,b);
- System.out.print(",");
- cnt++;
-
- /* end the line and start another if we are getting too long */
- if (cnt == 6)
- {
- System.out.println();
- System.out.print(" ");
- cnt = 0;
- }
- }
- }
-
- /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
- }
- /*=========================== COPYRIGHT NOTICE ===========================
-
- This file is part of the subArctic user interface toolkit.
-
- Copyright (c) 1996 Scott Hudson and Ian Smith
- All rights reserved.
-
- The subArctic system is freely available for most uses under the terms
- and conditions described in
- http://www.cc.gatech.edu/gvu/ui/sub_arctic/sub_arctic/doc/usage.html
- and appearing in full in the lib/interactor.java source file.
-
- The current release and additional information about this software can be
- found starting at: http://www.cc.gatech.edu/gvu/ui/sub_arctic/
-
- ========================================================================*/
-